package com.sdusoft.beans;

import java.sql.Timestamp;
import java.util.Date;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang.StringUtils;

import my.db.POJO;
import my.db.QueryHelper;
import my.mvc.ActionException;
import my.mvc.IUser;
import my.mvc.RequestContext;
import my.util.DateUtil;
import my.util.RequestUtils;
import my.util.ResourceUtils;

public class User extends POJO implements IUser {

	private static final long serialVersionUID = 8900579108799547822L;
	
	public static final User INSTANCE = new User();
	public static final String TableName = "sdu_users";

	public static void Logout(long userid) {
		return;
//		HttpSession session = RequestContext.get().request().getSession(false);
//		if(session!=null){
//			User user = (User) session.getAttribute("g_user");
//			System.out.println("-------remove user:"+user.getName()+" from session-----------");
//			session.removeAttribute(G_USER);
//		}
//		RequestContext.get().deleteUserInCookie();
	}

	private final static String POST_LOGIN = "UPDATE " + User.TableName
			+ " SET this_login_time=?,this_login_ip=? WHERE id=?";
	public static final String G_USER = "g_user";

	/**
	 * 根据登录信息获取用户,如果登录成功，修改用户状态值
	 * @param email
	 * @param pwd
	 * @param ip
	 * @return
	 */
	public static User Login(String email, String pwd, String ip) {
		if (StringUtils.isBlank(email) || StringUtils.isBlank(pwd))
			return null;
		User user = GetUserByEmail(email);
		if ((user != null && StringUtils.equalsIgnoreCase(user.pwd,
				DigestUtils.shaHex(pwd)))) {
			if (user.getStatus() == IUser.STATUS_NO) {
				String tip = ResourceUtils.getString("error","user_blocked", user.getEmail());
				throw new ActionException(tip);
			}
			if (ip.length() > 16)
				ip = "127.0.0.1";
			user.Evict(QueryHelper.update(POST_LOGIN, new Timestamp(
					System.currentTimeMillis()), ip, user.getId()) == 1);
			return user;
		}
		return null;
	}

	/**
	 * 根据用户的登录邮箱，获取用户详细信息，每天登录的次数不是很多，可以直接查库
	 * 
	 * @param email
	 * @return
	 */
	public static User GetUserByEmail(String email) {
		String sql = "select * from " + User.TableName
				+ " where email=?";
		User user = QueryHelper.read(User.class, sql, email);
		return user;
	}

	/**
	 * 返回当前登录用户的详细资料
	 * 
	 * @param req
	 * @return
	 */
	public static User GetLoginUser(HttpServletRequest req) {
		Object loginUser = req.getAttribute(G_USER);
		if (loginUser == null) {
			// 从Cookie中解析出用户id
			IUser cookie_user = RequestContext.get().getUserFromCookie();
			if (cookie_user == null){
				return null;
			}
			// 即使cookie中有这个用户的pwd，我们也要校验一下正确性
			User user = User.Read(cookie_user.getId());
			if (user != null
					&& StringUtils.equalsIgnoreCase(user.getPwd(),
							cookie_user.getPwd())) {
				user.PostLogin(req);
				return user;
			}
		}
		return (User)loginUser;
	}

	private static User Read(long id) {
		return User.INSTANCE.Get(id);
	}

	public void PostLogin(HttpServletRequest req) {
		boolean is_today = (getThis_login_time() == null) ? false : DateUtil
				.is_today(getThis_login_time());
		if (!is_today) {
			User.IncScore(getId(), SCORE.LOGIN);
		}
		if (getThis_login_time() == null || !is_today) {
			String ip = RequestUtils.getRemoteAddr(req);
			Evict(QueryHelper.update(POST_LOGIN,
					new Timestamp(System.currentTimeMillis()), ip, getId()) == 1);
		}
		req.setAttribute(G_USER, this);
	}

	private static void IncScore(long id, SCORE score) {
		//积分虽然增加，但是nick_name并不会立即变化，等每天晚上定时任务跑一下吧
		if(score.name().equals(SCORE.LOGIN.name())){
			String sql = "update "+TableName+" set score = score + "+5+" where id = "+id;
			QueryHelper.update(sql);
		}
	}

	@Override
	protected boolean IsObjectCachedByID() {
		return true;
	}

	@Override
	protected Map<String, Object> ListInsertableFields() {
		Map<String, Object> ret = super.ListInsertableFields();
		ret.remove("reg_time");
		return ret;
	}

	private String email;
	private String pwd;
	private String name;
	private String MSN;
	private String QQ;
	private String portrait;
	private byte gender;
	private Date birth;
	private String resume;
	private String company;
	private String job;
	private String province;
	private String city;
	private byte role;
	private int score;
	private int rank;
	private byte status;
	private Timestamp reg_time;
	private Timestamp this_login_time = new Timestamp(System.currentTimeMillis());
	private String this_login_ip;

	@Override
	public boolean IsBlocked() {
		// TODO:或者看IP，如果IP在IP阻止列表中也是有问题的
		return getStatus() == IUser.STATUS_NO;
	}

	@Override
	public String getPwd() {
		return this.pwd;
	}

	@Override
	public byte getRole() {
		return this.role;
	}

	// -----下面是一些没用的getter/setter
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getPortrait() {
		return portrait;
	}

	public void setPortrait(String portrait) {
		this.portrait = portrait;
	}

	public int getScore() {
		return score;
	}

	public void setScore(int score) {
		this.score = score;
	}

	public Timestamp getReg_time() {
		return reg_time;
	}

	public void setReg_time(Timestamp reg_time) {
		this.reg_time = reg_time;
	}

	public Timestamp getThis_login_time() {
		return this_login_time;
	}

	public void setThis_login_time(Timestamp this_login_time) {
		this.this_login_time = this_login_time;
	}

	public String getThis_login_ip() {
		return this_login_ip;
	}

	public void setThis_login_ip(String this_login_ip) {
		this.this_login_ip = this_login_ip;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public void setPwd(String pwd) {
		this.pwd = pwd;
	}

	public void setRole(byte role) {
		this.role = role;
	}

	public void setStatus(byte status) {
		this.status = status;
	}

	public String getEmail() {
		return email;
	}

	public byte getStatus() {
		return status;
	}

	public String getMSN() {
		return MSN;
	}

	public void setMSN(String mSN) {
		MSN = mSN;
	}

	public String getQQ() {
		return QQ;
	}

	public void setQQ(String qQ) {
		QQ = qQ;
	}

	public byte getGender() {
		return gender;
	}

	public void setGender(byte gender) {
		this.gender = gender;
	}

	public Date getBirth() {
		return birth;
	}

	public void setBirth(Date birth) {
		this.birth = birth;
	}

	public String getResume() {
		return resume;
	}

	public void setResume(String resume) {
		this.resume = resume;
	}

	public String getCompany() {
		return company;
	}

	public void setCompany(String company) {
		this.company = company;
	}

	public String getJob() {
		return job;
	}

	public void setJob(String job) {
		this.job = job;
	}

	public String getProvince() {
		return province;
	}

	public void setProvince(String province) {
		this.province = province;
	}

	public String getCity() {
		return city;
	}

	public void setCity(String city) {
		this.city = city;
	}

	public int getRank() {
		return rank;
	}

	public void setRank(int rank) {
		this.rank = rank;
	}
}
